home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / genial / func / plist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  7.6 KB  |  350 lines

  1. /*
  2.  * plist.c -- routines for manipulating lists of points
  3.  *
  4.  */
  5.  
  6. #include "common.h"
  7. #include "llist.h"
  8. #include "display.h"
  9. #include "ui.h"
  10. #include "reg.h"
  11. #include "log.h"
  12.  
  13. /* the current point list manipulated during region selection */
  14. static struct plist *cplhead = NULL, *cpltail = NULL;
  15.  
  16. /* the number of current points, and the point limit */
  17. static int ncp = 0, plim = 0;
  18.  
  19. /***********************************************************/
  20. void
  21. set_plist_globals(reg)
  22.     struct region *reg;
  23. {
  24.     if (reg != NULL) {
  25.     cplhead = reg->r_plist;
  26.     ncp = reg->r_plen+1;
  27.     cpltail = reg->r_plist;
  28.     set_region_plim(reg->r_type);    /* this sets plim */
  29.     if (reg->r_type == AN_TEXT && reg->r_sbs != NULL)
  30.         set_string(reg->r_sbs->string);
  31.     } else {
  32.     cplhead = cpltail = NULL;
  33.     ncp = 0;
  34.     set_region_plim(getrtype());
  35.     }
  36. }
  37.  
  38. /*********************************************/
  39. /* setplim() -- set point limit */
  40. int
  41. setplim(p)
  42.     int       p;
  43. {
  44.     plim = p;
  45. }
  46. /*********************************************/
  47. int
  48. getplim()
  49. {
  50.     return(plim);
  51. }
  52.  
  53. /******************************************************/
  54.  
  55. /* flush_cpl() -- flush the current point list (set reg->r_plist) */
  56. flush_cpl(reg)
  57.     struct region *reg;
  58. {
  59.     if (cplhead == NULL)
  60.     return;            /* necessary for use with logging */
  61.     reg->r_plist = cplhead;
  62.     reg->r_plen = ncp;
  63.     cplhead = cpltail = NULL;
  64.     ncp = 0;
  65. }
  66.  
  67. /* add_point adds a point to the current point list of the region */
  68. add_point(x, y)
  69.     int       x, y;
  70. {
  71.     struct plist *t;
  72.  
  73.     if (ncp >= plim) {
  74.     return;
  75.     }
  76.     t = (struct plist *) malloc(sizeof(struct plist));
  77.     t->pt.x = x;
  78.     t->pt.y = y;
  79.     cbget(orig_ximg, &t->cb, t->pt);
  80.     llist_add((llist *) t, (llist **) & cplhead, (llist **) & cpltail);
  81.     ncp++;
  82.     draw_cpl();
  83.     if (load_log == 0)
  84.     pvreg_set(cplhead);
  85.     curfunc->pvreg->r_plen++;
  86. }
  87.  
  88. /* add_log_point: same as add_point, but doesnt call draw_cpl() */
  89. add_log_point(x, y)
  90.     int       x, y;
  91. {
  92.     struct plist *t;
  93.  
  94.     if (ncp >= plim) {
  95.     return;
  96.     }
  97.     t = (struct plist *) malloc(sizeof(struct plist));
  98.     t->pt.x = x;
  99.     t->pt.y = y;
  100.     cbget(orig_ximg, &t->cb, t->pt);
  101.     llist_add((llist *) t, (llist **) & cplhead, (llist **) & cpltail);
  102.     ncp++;
  103.     if (load_log == 0)
  104.     pvreg_set(cplhead);
  105. }
  106.  
  107. /* delete a point from the current point list entry of the region */
  108. del_point(x, y)
  109.     int       x, y;
  110. {
  111.     XPoint    pt;
  112.     struct plist *t;
  113.  
  114.     pt.x = x;
  115.     pt.y = y;
  116.     if ((t = pfind(pt)) == NULL) {
  117.     XBell(display, 0);
  118.     return;
  119.     }
  120.     ref_cb(img_win->d_xid, &t->cb);
  121.     llist_del((llist *) t, (llist **) & cplhead, (llist **) & cpltail);
  122.     ncp--;
  123.     if (load_log == 0)
  124.     pvreg_set(cplhead);
  125. }
  126.  
  127. clear_plist()
  128. {
  129.     struct plist *t;
  130.  
  131.     for (t = cplhead; t != NULL; t = t->next) {
  132.     ref_cb(img_win->d_xid, &t->cb);
  133.     llist_del((llist *) t, (llist **) & cplhead, (llist **) & cpltail);
  134.     }
  135.     ncp = 0;
  136.     if (load_log == 0)
  137.     pvreg_set(cplhead);
  138. }
  139.  
  140. /* get the number of points in the currently selected region */
  141. int
  142. getnpoints()
  143. {
  144.     return ncp;
  145. }
  146.  
  147. /* set the number of points in the currently selected region */
  148. setnpoints(n)
  149. {
  150.     ncp = n;
  151. }
  152.  
  153. /* for use only by move_point.c: */
  154. struct plist
  155.          *
  156. getcpl()
  157. {
  158.     return cplhead;
  159. }
  160.  
  161. /* pl_find() -- find an entry in a point list with the exact coordinates of
  162.    the point passed to it. */
  163. struct plist
  164.          *
  165. pl_find(pnt, list)
  166.     XPoint    pnt;
  167.     struct plist *list;
  168. {
  169.     struct plist *tr;
  170.  
  171.     tr = list;
  172.     while (tr != NULL) {
  173.     if (tr->pt.x == pnt.x && tr->pt.y == pnt.y)
  174.         return tr;        /* it's gonna be deleted anyway, so we'll
  175.                  * just return the actual indice. */
  176.     tr = tr->next;
  177.     }
  178.     return NULL;
  179. }
  180.  
  181. /* cbget() -- get the backing store for a cross from an ximage */
  182. cbget(xi, bst, pt)
  183.     XImage   *xi;
  184.     struct cbstore *bst;
  185.     XPoint    pt;
  186. {
  187.     register int x, y;
  188.     /* check top of cross and bottom of cross for border hit... */
  189.  
  190.     bst->top.y = pt.y - CRSIZE;
  191.     bst->left.x = pt.x - CRSIZE;
  192.     bst->top.x = pt.x;
  193.     bst->left.y = pt.y;
  194.     bst->cht = CRSIZE * 2 + 1;
  195.     bst->cwt = CRSIZE * 2 + 1;
  196.     if (((int) pt.y - CRSIZE) < 0) {
  197.     bst->top.y = 0;
  198.     bst->cht = bst->cht - pt.y;
  199.     } else if (((int) pt.y + CRSIZE) > xi->height) {
  200.     bst->top.y = ((short) xi->height - (CRSIZE * 2));
  201.     bst->cht = bst->cht - (xi->height - pt.y);
  202.     }
  203.     if (((int) pt.x - CRSIZE) < 0) {
  204.     bst->left.x = 0;
  205.     bst->cwt = bst->cwt - pt.x;
  206.     }
  207.     if (((int) pt.x + CRSIZE) > xi->width) {
  208.     bst->left.x = ((short) xi->width - (CRSIZE * 2));
  209.     bst->cwt = bst->cwt - (xi->width - pt.x);
  210.     }
  211.     x = (int) bst->left.x;
  212.     y = (int) bst->left.y;
  213.     while (x <= (bst->left.x + bst->cwt)) {
  214.     bst->hvals[(x - bst->left.x)] = (unsigned char) XGetPixel(xi, x, y);
  215.     x++;
  216.     }
  217.     x = (int) bst->top.x;
  218.     y = (int) bst->top.y;
  219.     while (y <= (bst->top.y + bst->cht)) {
  220.     bst->vvals[(y - bst->top.y)] = (unsigned char) XGetPixel(xi, x, y);
  221.     y++;
  222.     }
  223. }
  224.  
  225. /***************************************************************/
  226. /* pfind() -- find an entry in a plist within 20 pixels' distance from the
  227.    given point */
  228. struct plist
  229.          *
  230. pfind(dpt)
  231.     XPoint    dpt;
  232. {
  233.     int       sm = 20;
  234.     int       dist;
  235.     struct plist *trp;
  236.  
  237.     /*
  238.      * We could do all sorts of neat things to optimize this.  but since
  239.      * there aren't  ever going to be more than a handful of points in the
  240.      * buffer, why bother?
  241.      */
  242.  
  243.     for (trp = cplhead; trp != NULL; trp = trp->next) {
  244.     dist = (int) irint(distance(trp->pt, dpt));
  245. #ifdef DEBUG
  246.     printf("distance to point:%d\n", dist);
  247. #endif
  248.     if (dist <= sm) {
  249.         return trp;
  250.     }
  251.     }
  252.     return NULL;
  253. }
  254.  
  255. /***************************************************************/
  256. /* draw_pl() -- refresh the crosses in a given plist */
  257. /* once called cr_refresh().... */
  258. draw_pl(listhead, dwin)
  259.     struct plist *listhead;
  260.     struct disp_win *dwin;
  261. {
  262.     register XGCValues gcval;
  263.     register struct plist *tr;
  264.  
  265.     gcval.foreground = standout;
  266.     XChangeGC(display, gc, GCForeground, &gcval);
  267.     for (tr = listhead; tr != NULL; tr = tr->next) {
  268.     draw_cb(dwin->d_xid, &(tr->cb));
  269.     }
  270. }
  271.  
  272. /* routine to draw a cross on the display */
  273. draw_cb(xid, cb)
  274.     XID       xid;
  275.     struct cbstore *cb;
  276. {
  277.     XPoint    pt;
  278.     int       len;
  279.  
  280.     itod_pt(&cb->top, &pt);
  281.     len = itod(cb->cht);
  282.     XDrawLine(display, xid, gc, pt.x, pt.y, pt.x, len + pt.y);
  283.     itod_pt(&cb->left, &pt);
  284.     len = itod(cb->cwt);
  285.     XDrawLine(display, xid, gc, pt.x, pt.y, len + pt.x, pt.y);
  286. }
  287.  
  288. /* refresh a cross from its backing store */
  289. ref_cb(xid, cb)
  290.     XID       xid;
  291.     struct cbstore *cb;
  292. {
  293.     /*
  294.      * should eventually add routines to checkand make sure no collisions
  295.      * with other crosses occur, but WE'LL WAIT....
  296.      */
  297.     register XGCValues gcval;
  298.     register int x, y, dx, dy;
  299.  
  300.     x = cb->top.x;
  301.     y = cb->top.y;
  302.  
  303. #ifdef DEBUG
  304.     printf("ref_cb: %d,%d \n", x, y);
  305. #endif
  306.  
  307.     dx = itod(x);
  308.     while (y <= (cb->top.y + cb->cht)) {
  309.     gcval.foreground = cb->vvals[(y - cb->top.y)];
  310.     XChangeGC(display, gc, GCForeground, &gcval);
  311.     dy = itod(y);
  312.     XDrawPoint(display, xid, gc, dx, dy);
  313.     y++;
  314.     }
  315.     x = cb->left.x;
  316.     y = cb->left.y;
  317.     dy = itod(y);
  318.     while (x <= (cb->left.x + cb->cwt)) {
  319.     gcval.foreground = cb->hvals[(x - cb->left.x)];
  320.     XChangeGC(display, gc, GCForeground, &gcval);
  321.     dx = itod(x);
  322.     XDrawPoint(display, xid, gc, dx, dy);
  323.     x++;
  324.     }
  325. }
  326.  
  327.  
  328. /* cr_refresh() -- refresh the backing store in a given plist */
  329. ref_pl(listhead, dwin)
  330.     struct plist *listhead;
  331.     struct disp_win *dwin;
  332. {
  333.     struct plist *tr;
  334.  
  335.     for (tr = listhead; tr != NULL; tr = tr->next) {
  336.     ref_cb(dwin->d_xid, &tr->cb);
  337.     }
  338. }
  339.  
  340. /* refresh the current point list */
  341. draw_cpl()
  342. {
  343. #ifdef TRACE_EX
  344.     fprintf(stderr, " in draw_cpl \n");
  345. #endif
  346.  
  347.     if (!clean_mode)
  348.        draw_pl(cplhead, img_win);
  349. }
  350.